<?php

namespace app\api\service\vippay;

use app\api\model\dealer\Referee as RefereeModel;
use app\api\service\Basics;
use app\api\model\User as UserModel;
use app\api\model\vipcard\OrderPlan as OrderPlanModel;
use app\api\model\vipcard\Order as OrderModel;
use app\api\model\user\MoneyLog as MoneyLogModel;
use app\common\enum\user\moneylog\Scene as MoneySceneEnum;
use app\api\model\user\PointsLog as PointsLogModel;
use app\common\enum\user\pointslog\Scene as PointsSceneEnum;
use app\common\enum\recharge\order\PayStatus as PayStatusEnum;
use app\common\library\MysicLog;
use app\common\model\dealer\Order as DealerOrderModel;
use app\common\model\SingleOrder as SingleOrderModel;
use app\common\model\Wxapp as WxappModel;
use app\factory\MqFactory;
use org\RabbitMQ;
use think\Db;
use think\Exception;
use think\exception\PDOException;



class PaySuccess extends Basics
{
    // 订单模型
    public $model;

    // 当前用户信息
    private $user;

    // 当前订单快照
    private $orderplan;

    protected $mysicLog;
    /**
     * 构造函数
     * PaySuccess constructor.
     * @param $orderNo
     * @throws \think\exception\DbException
     */
    public function __construct($orderNo)
    {

        // 实例化订单模型 123
        $this->model = OrderModel::getPayDetail($orderNo);
        $this->wxappId = $this->model['wxapp_id'];
        // 获取用户信息
        $this->user = UserModel::detail($this->model['user_id']);
        // 获取订单快照
        $this->orderplan = OrderPlanModel::detail($this->model['order_id']);
        $this->mysicLog = MysicLog::instance();
    }

    protected function log($pre,$data = null)
    {
        $fileName = 'fenhong-vip-queue'.date('Ymd', time()).'.log';
        if(!file_exists($fileName)) {
            if($data) {
                $data = is_array($data) ? json_encode($data) : $data;
                file_put_contents($fileName,  $pre . $data .  PHP_EOL, FILE_APPEND);
            } else {
                file_put_contents($fileName,  $pre .  PHP_EOL, FILE_APPEND);
            }
            chmod($fileName, 0766);
        }else {
            if($data) {
                $data = is_array($data) ? json_encode($data) : $data;
                file_put_contents($fileName,  $pre . $data .  PHP_EOL, FILE_APPEND);
            } else {
                file_put_contents($fileName,  $pre .  PHP_EOL, FILE_APPEND);
            }
        }
    }

    /**
     * 获取订单详情
     * @return OrderModel|null
     */
    public function getOrderInfo()
    {
        return $this->model;
    }

    /**
     * 订单支付成功业务处理
     * @param int $payType 支付类型
     * @param array $payData 支付回调数据
     * @return bool
     */
    public function onPaySuccess($payType, $payData)
    {

        $this->mysicLog->setFilename('notify/order');
        $this->mysicLog->info($payType, '支付类型');
        $this->mysicLog->info(json_encode($payData), '支付数据');
        $this->mysicLog->info([
            '订单ID' => $this->model->order_id, '用户id'=>$this->model->user_id, '订单编号' => $this->model->order_no,'商品总金额(不含优惠折扣)' => $this->model->total_price,
            '订单金额(含优惠折扣)' => $this->model->order_price, '实际付款金额(包含运费)' => $this->model->pay_price, '后台修改的订单金额（差价）' =>  $this->model->pay_price,
            '支付方式(10余额支付 20微信支付)' => $this->model->pay_type['value'], '付款状态(10未付款 20已付款)' => $this->model->pay_status['value'],'付款时间' =>$this->model->pay_time,
            '订单状态(10进行中 20取消 21待取消 30已完成)'=>$this->model->order_status['value'], '订单来源(10普通订单 20砍价订单 30秒杀订单 40购买会员订单 50当面付订单)' => $this->model->order_source,
            '是否为虚拟物品(1是 2不是)' => $this->model->is_fictitious,'分红与否(0未分红 1已份红)'=>$this->model->is_abouns
        ], '订单信息');
        $this->mysicLog->info('开始', '更新订单付款状态');
        $status = false;

        $status = $this->model->save([
            'order_status'=>30,//订单状态(10进行中 20取消 21待取消 30已完成)
            'delivery_status'=>20,//发货状态(10未发货 20已发货)
            'delivery_time'=>time(),//发货时间
            'receipt_status'=>20,//收货状态(10未收货 20已收货)
            'receipt_time'=>time(),//收货时间
            'delivery_type'=>20,//配送方式(10快递配送 20上门自提)
            'is_settled'=>1,//订单是否已结算(0未结算 1已结算)
            'pay_status' => PayStatusEnum::SUCCESS,//订单状态
            'pay_time' => time(),//支付时间
            'transaction_id' => $payData['transaction_id'],//微信的交易号
        ]);
        $this->mysicLog->info(bool2str($status), '订单状态更新结果');
        try {
            $this->updatePayStatus($payType, $payData);
        } catch(\Exception $e) {
            $this->mysicLog->error(exceptionLogFormat($e), '更新用户余额，用户等级，单条订单记录表加数据，用户积分变动明细，发放分销佣金时异常');
        }
        // 更新付款状态

        // 订单支付成功行为
        if ($status == true) {
            $wxApp = db('wxapp')->where('wxapp_id', $this->model['wxapp_id'])->find();
            $rem = MqFactory::instance();
            if(2 == $wxApp['service_type']) {
                $data=['orderNo'=> $this->model['order_no'],'time'=>time()];
                $this->mysicLog->info($data, '成功订单入队列-微股客服务商');
                $rem->send($data,'new-share','refund','refund');
            } else {
                $data=['orderId'=> $this->model['order_id'],'time'=>time()];
                $this->mysicLog->info($data, '成功订单入队列-龙达服务商');
                $rem->send($data,'userListData','userListDataLog','userListDataLog');
            }
        }
        return $status;
    }


    /**
     * 储值卡余额为0支付成功业务处理
     * @param int $payType 支付类型
     * @param array $payData 支付回调数据
     * @return bool
     */
    public function freePaySuccess($payType)
    {

        $this->mysicLog->setFilename('notify/order');
        $this->mysicLog->info($payType, '支付类型');

        $this->mysicLog->info([
            '订单ID' => $this->model->order_id, '用户id'=>$this->model->user_id, '订单编号' => $this->model->order_no,'商品总金额(不含优惠折扣)' => $this->model->total_price,
            '订单金额(含优惠折扣)' => $this->model->order_price, '实际付款金额(包含运费)' => $this->model->pay_price, '后台修改的订单金额（差价）' =>  $this->model->pay_price,
            '支付方式(10余额支付 20微信支付)' => $this->model->pay_type['value'], '付款状态(10未付款 20已付款)' => $this->model->pay_status['value'],'付款时间' =>$this->model->pay_time,
            '订单状态(10进行中 20取消 21待取消 30已完成)'=>$this->model->order_status['value'], '订单来源(10普通订单 20砍价订单 30秒杀订单 40购买会员订单 50当面付订单)' => $this->model->order_source,
            '是否为虚拟物品(1是 2不是)' => $this->model->is_fictitious,'分红与否(0未分红 1已份红)'=>$this->model->is_abouns
        ], '订单信息');
        $this->mysicLog->info('开始', '更新订单付款状态');

        $status = $this->model->save([
            'order_status'=>30,//订单状态(10进行中 20取消 21待取消 30已完成)
            'delivery_status'=>20,//发货状态(10未发货 20已发货)
            'delivery_time'=>time(),//发货时间
            'receipt_status'=>20,//收货状态(10未收货 20已收货)
            'receipt_time'=>time(),//收货时间
            'delivery_type'=>20,//配送方式(10快递配送 20上门自提)
            'is_settled'=>1,//订单是否已结算(0未结算 1已结算)
            'pay_status' => PayStatusEnum::SUCCESS,//订单状态
            'pay_time' => time(),//支付时间
            'transaction_id' => "",//微信的交易号
        ]);
        $this->mysicLog->info(bool2str($status), '订单状态更新结果');
        try {
            $this->updatePayStatus($payType);
        } catch(\Exception $e) {
            $this->mysicLog->error(exceptionLogFormat($e), '更新用户余额，用户等级，单条订单记录表加数据，用户积分变动明细，发放分销佣金时异常');
        }

        return $status;
    }


  /**
     * 更新付款状态
     * @param $payType
     * @param array $payData
     * @return bool
     */
    private function updatePayStatus($payType, $payData = [])
    {


            $this->mysicLog->setFilename('notify/viporder');

//        return $this->model->transaction(function () use ($payType, $payData) {

            // +----------------------------------------------------------------------
            // | 用户总支付的金额、充值余额、用户可用积分变更---user
            // +----------------------------------------------------------------------
            Db::name('user')->where(['user_id'=>$this->user['user_id']])->setInc('pay_money',$this->model['pay_price']);
            $this->mysicLog->info("成功", '用户总支付的金额变更');

            Db::name('user')->where(['user_id'=>$this->user['user_id']])->setInc('money',$this->orderplan['card_money']);
            $this->mysicLog->info("成功", '充值余额变更');

            Db::name('user')->where(['user_id'=>$this->user['user_id']])->setInc('points',$this->orderplan['reward_point']);
            $this->mysicLog->info("成功", '用户可用积分变更');

            // +----------------------------------------------------------------------
            // | 更新用户等级---user
            // +----------------------------------------------------------------------
            if($this->user['vip_level']<=$this->orderplan['card_id']){
                Db::name('user')->where(['user_id'=>$this->user['user_id']])->update(['vip_level'=>$this->orderplan['card_id']]);
                $this->mysicLog->info("成功", '用户等级变更');
            }

            // +----------------------------------------------------------------------
            // | 用户单条订单记录表加数据---single_order
            // +----------------------------------------------------------------------
            $orderData['amount'] = $this->model['pay_price'];
            $orderData['pay_type'] = 40;
            $orderData['wxapp_id']=$this->model['wxapp_id'];
            $orderData['user_id']=$this->user['user_id'];

            $this->singleOrder(['wxapp_id'=>$this->model['wxapp_id'],'user_id'=>$this->user['user_id']],$orderData);
            $this->mysicLog->info("成功", '用户单条订单记录表加数据成功');


            // +----------------------------------------------------------------------
            // | 用户余额变动明细加数据---user_money_log
            // +----------------------------------------------------------------------
            $money_log = [
                'user_id' => $this->user['user_id'],
                'scene'=>10,
                'money' => $this->orderplan['card_money'],
                'order_no' => $this->model['order_no'],
                'wxapp_id' => $this->orderplan['wxapp_id'],
                'create_time' => time(),
            ];
            $this->mysicLog->info($money_log, '用户余额变动数据');
            if($this->orderplan['card_money']>0){
                $money_log_status = Db::name('user_money_log')->insertGetId($money_log);
                $this->mysicLog->info($money_log_status, '用户余额变动数据结果');
            }


            // +----------------------------------------------------------------------
            // | 用户积分变动明细加数据---user_points_log
            // +----------------------------------------------------------------------
            $points_Log = [
                'user_id' => $this->user['user_id'],
                'scene'=>10,
                'value' => $this->orderplan['reward_point'],
                'order_no' => $this->model['order_no'],
                'wxapp_id' => $this->orderplan['wxapp_id'],
                'create_time' => time(),
            ];
            $this->mysicLog->info($points_Log, '用户积分变动明细数据');
            if($this->orderplan['reward_point']>0){
                $points_log_status = Db::name('user_points_log')->insertGetId($points_Log);
                $this->mysicLog->info($points_log_status, '用户积分变动数据结果');
            }



            // +----------------------------------------------------------------------
            // | 发放分销佣金
            // +----------------------------------------------------------------------

            //DealerOrderModel::grantVipMoney($this->model,30,20);
            $this->grantMoney($this->model);
            return true;
        //});


    }



    /**
     * 发放储值卡分销订单佣金
     * @param array|\think\Model $order 订单详情
     * @param int $orderType 订单类型
     * @return bool|false|int
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function grantMoney($data)
    {
        $this->mysicLog->setFilename('notify/viporder');
        $this->mysicLog->info("开始", '发放储值卡分销订单佣金');

        // +----------------------------------------------------------------------
        // | 获取分销方案
        // +----------------------------------------------------------------------
        $dealer_case = WxappModel::dealerCase($data['wxapp_id']);
        $this->mysicLog->info($dealer_case, '获取分销方案');

        // +----------------------------------------------------------------------
        // | 获取上级ID
        // +----------------------------------------------------------------------
        $refereeId = RefereeModel::isExistReferee($data['user_id']);
        $this->mysicLog->info($refereeId, '获取上级ID');

        if ($refereeId) {
            $refereeModel = new UserModel;
            // +----------------------------------------------------------------------
            // | 上级详情
            // +----------------------------------------------------------------------
            $refereeInfo = $refereeModel::detail($refereeId);
            if($refereeInfo){
                $userData = [
                    'user_id'=>$refereeInfo['user_id'],
                    'nickName'=>$refereeInfo['nickName'],
                    'pay_money'=>$refereeInfo['pay_money'],
                    'shareholder'=>$refereeInfo['shareholder'],
                    'vip_level'=>$refereeInfo['vip_level'],
                    'is_staff'=>$refereeInfo['is_staff'],
                    'deacler'=>$refereeInfo['deacler'],
                ];
                $this->mysicLog->info($userData, '上级详情');
            }


            // +----------------------------------------------------------------------
            // | 查看分红比例
            // +----------------------------------------------------------------------
            $card = Db::name('wxapp_card_order_plan')->where(['order_id'=>$data['order_id']])->find();
            if($card){
                $this->mysicLog->info($card, '获取购买时会员卡的详情');
            }
            $reward_percent = $card['reward_percent'];
            $this->mysicLog->info($reward_percent, '储值卡设置的赏金比例');

            // +----------------------------------------------------------------------
            // | 获取当前分销方案一的配置
            // +----------------------------------------------------------------------
            $dealer_setting_one = Db::name("distribution_setting")->where(['wxapp_id'=>$data['wxapp_id'],'dealer_type'=>1])->value('setting_content');
            $this->mysicLog->info($dealer_setting_one, '获取当前分销方案一的配置');

            // +----------------------------------------------------------------------
            // | 获取当前分销方案二的配置
            // +----------------------------------------------------------------------
            $dealer_setting_tow = Db::name("distribution_setting")->where(['wxapp_id'=>$data['wxapp_id'],'dealer_type'=>2])->value('setting_content');
            $this->mysicLog->info($dealer_setting_tow, '获取当前分销方案二的配置');

            // +----------------------------------------------------------------------
            // | 获取上级用户的单笔支付金额
            // +----------------------------------------------------------------------
            $amount = Db::name("single_order")->where(['wxapp_id'=>$data['wxapp_id'],'user_id'=>$refereeId])->value('amount');
            $this->mysicLog->info($amount?$amount:0, '获取上级用户的总支付金额');


            // +----------------------------------------------------------------------
            // | 如果为分销方案一
            // +----------------------------------------------------------------------
            if($dealer_case==1){
                $checkDealer = $refereeModel->getConfigByUserType($refereeInfo,$type="card");
                $this->mysicLog->info($checkDealer?$checkDealer:[], '获取分销方案一对应的参数');
                if ($checkDealer && $reward_percent>0) {
                    //计算分销佣金
                    $dealer_money = bcsub($data['pay_price']* ($reward_percent * 0.01),0, 2);
                    $this->mysicLog->info($dealer_money?$dealer_money:0, '计算分销佣金');
                    //创建分销订单
                    if($dealer_money>0){
                        $dealer_order_id = $this->createDealerOrder($data,$refereeId,$dealer_money,$dealer_case);
                        //分销佣金明细加数据
                        $this->otherOrder($dealer_order_id);
                    }else{
                        $this->mysicLog->info("分销佣金不满足条件", '计算分销佣金');
                    }

                }else{
                    $this->mysicLog->info("不满足分销条件", '不满足分销条件分销方案一');
                }

            }elseif($dealer_case==2){//分销方案二
                $checkDealerTow = $refereeInfo->getDealerTow($refereeInfo,$type="card_status");
                $this->mysicLog->info($checkDealerTow?$checkDealerTow:0, '获取分销方案二的分销比例');
                if($checkDealerTow){
                    //计算分销佣金
                    $dealer_money = bcsub($data['pay_price']* ($checkDealerTow * 0.01),0, 2);
                    $this->mysicLog->info($dealer_money?$dealer_money:0, '计算分销佣金');
                    //创建分销订单
                    if($dealer_money>0){
                        $dealer_order_id = $this->createDealerOrder($data,$refereeId,$dealer_money,$dealer_case);
                        //分销佣金明细加数据
                        $this->otherOrder($dealer_order_id);
                    }else{
                        $this->mysicLog->info("分销佣金不满足条件", '计算分销佣金');
                    }

                }else{
                    $this->mysicLog->info("不满足分销条件", '不满足分销条件分销方案二');
                }
            }


        }else{
            $this->mysicLog->info("没有上级", '没有上级');
        }


    }


    /**
     * 分销佣金明细表处理
     * @param $order
     * @param int $order_type
     * @return bool|false|int
     * @throws \think\exception\DbException
     */
    public function otherOrder($dealer_order_id)
    {

        // 分销订单详情
        $dealerOrder = Db::name('dealer_order')->find($dealer_order_id);
        if(!$dealerOrder){
            $this->mysicLog->info("无分销订单", '无分销订单');
            return false;
        }
        $this->mysicLog->info($dealerOrder, '发放储值卡分销订单佣金分销订单详情');

        $this->mysicLog->info($dealerOrder['first_money'], '分销商用户记录表dealer_user，分销佣金');
        $this->mysicLog->info($dealerOrder['first_user_id'], '分销商用户记录表dealer_user，上级id');

        if($dealerOrder['first_user_id']>0 && $dealerOrder['first_money']>0){
            // +----------------------------------------------------------------------
            // | dealer_user表更新数据----分销商用户记录表
            // +----------------------------------------------------------------------
            Db::name('dealer_user')
                ->where(['user_id'=>$dealerOrder['first_user_id']])
                ->setInc('money', $dealerOrder['first_money']);


            // +----------------------------------------------------------------------
            // | dealer_capital表加数据----分销商资金明细表
            // +----------------------------------------------------------------------
            $capitalData = [
                'user_id'=>$dealerOrder['first_user_id'],
                'flow_type'=>20,
                'money'=>$dealerOrder['first_money'],
                'wxapp_id'=>$dealerOrder['wxapp_id'],
                'create_time'=>time(),
                'update_time'=>time(),
            ];

            $this->mysicLog->info($capitalData, '分销商资金明细表数据');
            $dealer_capital_id = Db::name('dealer_capital')->insertGetId($capitalData);

            $this->mysicLog->info($dealer_capital_id, '获取分销商资金明细表ID');
        }


    }

    /**
     * 创建分销订单
     * @param $order
     * @param int $order_type
     * @return bool|false|int
     * @throws \think\exception\DbException
     */
    public function createDealerOrder($data,$refereeId,$dealer_money,$dealer_case)
    {

        $dealer_order = [
            'user_id' => $data['user_id'],//用户id (买家)
            'order_id' => $data['order_id'],//订单id
            'order_type' => 30,//订单类型(10商城订单 20拼团订单 30 购买vip 40 购买爆品礼 50 当面付 60分红转化)
            'order_price' => $data['order_price'],//订单总金额
            'first_user_id' => $refereeId,//分销商用户id(一级)
            'second_user_id' => 0,//分销商用户id(二级)
            'third_user_id' => 0,//分销商用户id(三级)
            'first_money' => $dealer_money,//分销佣金(一级)
            'second_money' => 0,//分销佣金(二级)
            'third_money' => 0,//分销佣金(三级)
            'is_invalid' => 0,//订单是否失效(0未失效 1已失效)
            'is_settled' => 1,//是否已结算佣金(0未结算 1已结算)
            'settle_time' => time(),//结算时间
            'wxapp_id' => $data['wxapp_id'],//小程序id
            'create_time' => time(),//创建时间
            'update_time' => time(),//更新时间
            'dealer_case' =>  $dealer_case,//分销方案
        ];

        $this->mysicLog->info($dealer_order, '计算分销佣金');
        $dealer_order_id = Db::name('dealer_order')->insertGetId($dealer_order);
        $this->mysicLog->info($dealer_order_id, '获取分销订单id');
        return $dealer_order_id;


    }


    /**
     * 用户单条订单记录表
     * @param int $payType 支付类型
     * @param array $payData 支付回调数据
     * @return bool
     */

    public function singleOrder($where,$data){
        //分销商表
        $flag = Db::name('single_order')->where($where)->find();
        if(!$flag){
            $single_data = [
                'amount'=>$data['amount'],
                'wxapp_id'=>$data['wxapp_id'],
                'pay_type'=>$data['pay_type'],
                'user_id'=>$data['user_id'],
                'create_time'=>time(),
                'update_time'=>time(),
            ];
            Db::name('single_order')->insertGetId($single_data);
        }else{
            if($flag['amount']<$data['amount']){
                $data['update_time'] = time();
                Db::name('single_order')->where($where)->update($data);
            }
        }
    }
}